package com.xdhl.fu.fi.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xdhl.fu.common.core.domain.R;
import com.xdhl.fu.common.core.utils.GaodMapUtils;
import com.xdhl.fu.common.core.utils.StringUtils;
import com.xdhl.fu.common.core.utils.bean.BeanUtils;
import com.xdhl.fu.common.core.utils.uuid.UUID;
import com.xdhl.fu.common.core.web.controller.BaseController;
import com.xdhl.fu.common.core.web.domain.AjaxResult;
import com.xdhl.fu.common.core.web.page.TableDataInfo;
import com.xdhl.fu.common.log.annotation.Log;
import com.xdhl.fu.common.log.enums.BusinessType;
import com.xdhl.fu.common.security.annotation.InnerAuth;
import com.xdhl.fu.common.security.annotation.RequiresPermissions;
import com.xdhl.fu.common.security.utils.SecurityUtils;
import com.xdhl.fu.fi.repository.MGFlightScheduleRepository;
import com.xdhl.fu.fi.service.IFlightAirportInfoService;
import com.xdhl.fu.fi.service.IFlightInfoService;
import com.xdhl.fu.flight.info.api.domain.FlightAirportInfo;
import com.xdhl.fu.flight.info.api.domain.FlightInfo;
import com.xdhl.fu.flight.info.api.domain.vo.FlightInfoVO;
import com.xdhl.fu.flight.info.api.mongodb.domain.MGFlightSchedule;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 航线信息Controller
 *
 * @author 朱力维
 * @date 2022-05-28
 */
@RestController
@RequestMapping("/info")
public class FlightInfoController extends BaseController {

    @Resource
    private IFlightInfoService flightInfoService;

    @Resource
    private MGFlightScheduleRepository mgFlightScheduleRepository;

    @Resource
    private IFlightAirportInfoService flightAirportInfoService;

    /**
     * 查询中转条件的航班
     */
    @RequiresPermissions("flight:info:adapt")
    @GetMapping("/list/transfer")
    public TableDataInfo listTransferByDataId(FlightInfoVO queryParams) {
        startPage();
        LambdaQueryWrapper<FlightInfo> condition = new LambdaQueryWrapper();
        List<FlightInfo> list = flightInfoService.list(condition);

        return getDataTable(list);
    }

    /**
     * 获取航班信息详细信息
     */
    @InnerAuth
    @GetMapping(value = "/getInfoInnerAuth/{dataId}")
    public R<MGFlightSchedule> getInfoInnerAuth(@PathVariable("dataId") String dataId) {
        Optional<MGFlightSchedule> mgFlightSchedule = mgFlightScheduleRepository.findById(dataId);
        return R.ok(mgFlightSchedule.orElse(new MGFlightSchedule()));
    }

    /**
     * 查询航线信息列表
     */
    @RequiresPermissions("flight:info:list")
    @GetMapping("/list")
    public TableDataInfo list(FlightInfo flightInfo) {
        startPage();
        LambdaQueryWrapper<FlightInfo> wrapper = new LambdaQueryWrapper<>();
        // 航班号
        wrapper.eq(StringUtils.isNotBlank(flightInfo.getFlightNumber()), FlightInfo::getFlightNumber, flightInfo.getFlightNumber());
        // 机型
        wrapper.eq(StringUtils.isNotBlank(flightInfo.getAircraftModel()), FlightInfo::getAircraftModel, flightInfo.getAircraftModel());
        // 航班类型
        wrapper.eq(StringUtils.isNotBlank(flightInfo.getFlightType()), FlightInfo::getFlightType, flightInfo.getFlightType());
        // 始发站
        wrapper.eq(StringUtils.isNotBlank(flightInfo.getStartStation()), FlightInfo::getStartStation, flightInfo.getStartStation());
        // 终点站
        wrapper.eq(StringUtils.isNotBlank(flightInfo.getEndStation()), FlightInfo::getEndStation, flightInfo.getEndStation());
        List<FlightInfo> list = flightInfoService.list(wrapper);
        return getDataTable(list);
    }

    /**
     * 获取航线信息详细信息
     */
    @RequiresPermissions("flight:info:query")
    @GetMapping(value = "/{dataId}")
    public AjaxResult getInfo(@PathVariable("dataId") String dataId) {
        return AjaxResult.success(flightInfoService.getById(dataId));
    }

    /**
     * 新增中转航线信息
     */
    @Transactional
    @RequiresPermissions("flight:info:add")
    @Log(title = "航线信息", businessType = BusinessType.INSERT)
    @PostMapping("/group")
    public AjaxResult addGroup(@RequestBody FlightInfoVO flightInfo) throws Exception {

        AjaxResult result;

        // 第一段航班
        FlightInfo first = new FlightInfo();
        // 第二段航班
        FlightInfo second = new FlightInfo();

        BeanUtils.copyBeanProp(first, flightInfo);
        BeanUtils.copyBeanProp(second, flightInfo.getGroup());

        String group = UUID.randomUUID().toString().replaceAll("-", StringUtils.EMPTY);

        // 计算第一段航班的城市名和机场名
        LambdaQueryWrapper<FlightAirportInfo> firstStartAirportWrapper = new LambdaQueryWrapper<>();
        firstStartAirportWrapper.eq(FlightAirportInfo::getCityCode, first.getStartStation());
        FlightAirportInfo firstStart = flightAirportInfoService.getOne(firstStartAirportWrapper);
        LambdaQueryWrapper<FlightAirportInfo> firstEndAirportWrapper = new LambdaQueryWrapper<>();
        firstEndAirportWrapper.eq(FlightAirportInfo::getCityCode, first.getEndStation());
        FlightAirportInfo firstEnd = flightAirportInfoService.getOne(firstEndAirportWrapper);
        String firstStartCityName = firstStart.getCityName();
        String firstStartAddress = firstStart.getLabel().split(",")[0];
        String firstEndCityName = firstEnd.getCityName();
        String firstEndAddress = firstEnd.getLabel().split(",")[0];

        first.setCreateBy(SecurityUtils.getUsername());
        first.setCreateTime(LocalDateTime.now());
        first.setUpdateBy(first.getCreateBy());
        first.setUpdateTime(first.getCreateTime());
        first.setDistance(GaodMapUtils.getDistance(firstStartCityName, firstStartAddress, firstEndCityName, firstEndAddress));
        first.setFGroup(group);
        first.setFGroupOrder(0);

        // 计算第二段航班的城市名和机场名
        LambdaQueryWrapper<FlightAirportInfo> secondStartAirportWrapper = new LambdaQueryWrapper<>();
        secondStartAirportWrapper.eq(FlightAirportInfo::getCityCode, first.getEndStation());
        FlightAirportInfo secondStart = flightAirportInfoService.getOne(secondStartAirportWrapper);
        LambdaQueryWrapper<FlightAirportInfo> secondEndAirportWrapper = new LambdaQueryWrapper<>();
        secondEndAirportWrapper.eq(FlightAirportInfo::getCityCode, second.getEndStation());
        FlightAirportInfo secondEnd = flightAirportInfoService.getOne(secondEndAirportWrapper);
        String secondStartCityName = secondStart.getCityName();
        String secondStartAddress = secondStart.getLabel().split(",")[0];
        String secondEndCityName = secondEnd.getCityName();
        String secondEndAddress = secondEnd.getLabel().split(",")[0];

        second.setStartStation(first.getEndStation());
        second.setCreateBy(SecurityUtils.getUsername());
        second.setCreateTime(LocalDateTime.now());
        second.setUpdateBy(second.getCreateBy());
        second.setUpdateTime(second.getCreateTime());
        second.setDistance(GaodMapUtils.getDistance(secondStartCityName, secondStartAddress, secondEndCityName, secondEndAddress));
        second.setFlightType(first.getFlightType());
        second.setFGroup(group);
        second.setFGroupOrder(1);

        // 根据航班类型进行某些特殊处理后入库
        switch (flightInfo.getFlightType()) {
            case "B":
                flightInfoService.save(first);
                flightInfoService.save(second);

                result = AjaxResult.success("新增成功");
                break;
            case "C":
                second.setFlightNumber(first.getFlightNumber());
                second.setAircraftModel(first.getAircraftModel());

                flightInfoService.save(first);
                flightInfoService.save(second);

                result = AjaxResult.success("新增成功");
                break;
            default:
                result = AjaxResult.error("无效的航班类型。");
                break;
        }
        return result;
    }

    /**
     * 新增航线信息
     */
    @Transactional
    @RequiresPermissions("flight:info:add")
    @Log(title = "航线信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FlightInfo flightInfo) {
        flightInfo.setCreateBy(SecurityUtils.getUsername());
        flightInfo.setCreateTime(LocalDateTime.now());
        flightInfo.setUpdateBy(flightInfo.getCreateBy());
        flightInfo.setUpdateTime(flightInfo.getCreateTime());
        return toAjax(flightInfoService.save(flightInfo));
    }

    /**
     * 修改航线信息
     */
    @Transactional
    @RequiresPermissions("flight:info:edit")
    @Log(title = "航线信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FlightInfo flightInfo) throws Exception {
        return toAjax(flightInfoService.updateById(flightInfo));
    }

    /**
     * 删除编组航线信息
     */
    @Transactional
    @RequiresPermissions("flight:info:remove")
    @Log(title = "航线信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/group/{groupId}")
    public AjaxResult removeGroupIds(@PathVariable String groupId) {
        LambdaQueryWrapper<FlightInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FlightInfo::getFGroup, groupId);
        return toAjax(flightInfoService.remove(wrapper));
    }

    /**
     * 删除航线信息
     */
    @Transactional
    @RequiresPermissions("flight:info:remove")
    @Log(title = "航线信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{dataIds}")
    public AjaxResult remove(@PathVariable String[] dataIds) {
        return toAjax(flightInfoService.removeByIds(Arrays.asList(dataIds)));
    }

}
